package com.wanshu.config;

import com.wanshu.sys.filter.TokenLoginFilter;
import com.wanshu.sys.filter.TokenVerifyFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import javax.annotation.Resource;
import java.util.Arrays;

/**
 * 我的安全配置
 * SpringSecurity 配置类
 *
 * @author 张颖辉（zyh）
 * @version 1.0.0
 * @date 2023/06/10
 */

@Configuration
public class MySpringSecurityConfiguration extends WebSecurityConfigurerAdapter {


    /**
     * 用户详细信息服务  具体的用户认证逻辑（查库，数据对比）
     */
    @Resource
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService) // 绑定用户详情服务: 具体的用户认证逻辑
                .passwordEncoder(new BCryptPasswordEncoder()); //绑定密码加密器
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //默认阻止csrf攻击，这里关闭csrf防护
                .csrf().disable()
                //允许基于HttpServletRequest限制访问
                .authorizeRequests()
                //允许放过的请求
                .antMatchers("/doc.html", "/doc.html/**", "/webjars/**", "/v2/**", "/swagger-resources",
                        "/swagger-resources/**", "/swagger-ui.html", "/swagger-ui.html/**","/v3/api-docs").permitAll()
                //指定任何经过身份验证的用户都允许访问
                .anyRequest().authenticated()
                .and()
                //跨域配置源 跨域
                .cors().configurationSource(corsConfigurationSource())
                .and()
                // 添加过滤器
                .addFilter(new TokenLoginFilter(super.authenticationManager())) // 绑定认证的过滤器
                .addFilter(new TokenVerifyFilter(super.authenticationManager())) // 绑定校验的过滤器
                //设置会话创建策略：无状态
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    /**
     * 跨域配置源
     *
     * @return {@link CorsConfigurationSource }
     * @author 张颖辉（zyh）
     * @date 2023/06/13
     * @version 1.0.0
     */
    private CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        //配置跨域拦截的相关信息
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowedMethods(Arrays.asList("*"));
        config.setAllowedOrigins(Arrays.asList("*"));
        config.setMaxAge(3600l);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }

}
